import 'package:dio/dio.dart';
import 'package:meiyunapp/common/url_base.dart';
import 'package:meiyunapp/net/base/base_entity.dart';
import 'package:meiyunapp/net/base/error_entity.dart';

import 'header_interceptor.dart';
import 'base/base_list_entity.dart';

class ApiService {
  Dio? _dio;

  ApiService._newInstance() {
    _dio = createDio();
  }

  static final ApiService _instance = ApiService._newInstance();

  static ApiService get instance {
    return _instance;
  }

  Dio createDio() {
    if (_dio == null) {
      var options = BaseOptions(
        baseUrl: UrlBase.getBaseUrl(),
        connectTimeout: 5000,
        receiveTimeout: 3000,
      );
      _dio = Dio(options);
      _dio!.interceptors.add(HeaderInterceptor());
      /*_dio!.interceptors.add(
        InterceptorsWrapper(
          onRequest: (request, handler) {
            print("\n================== 请求数据 ==========================");
            print("url = ${request.uri.toString()}");
            print("headers = ${request.headers}");
            print("params = ${request.data}");
            return handler.next(request);
          },
          onResponse: (response, handler) {
            print("\n================== 响应数据 ==========================");
            print("code = ${response.statusCode}");
            print("data = ${response.data}");
            print("\n");
            return handler.next(response);
          },
          onError: (e, handler) {
            print("\n================== 错误响应数据 ======================");
            print("type = ${e.type}");
            print("message = ${e.message}");
            print("\n");
            return handler.next(e);
          },
        ),
      );*/
    }
    return _dio!;
  }

  Future requestList<T>(String path,
      {Method method = Method.POST,
      dynamic params,
      required Function(List<T>) success,
      required Function(ErrorEntity) error}) async {
    _dio ??= createDio();

    Response response = await _dio!.request(path,
        data: params, options: Options(method: MethodValues[method]));

    try {
      if (response.statusCode == 200) {
        BaseListEntity<T> entity = BaseListEntity<T>.fromJson(response.data);
        if (entity.state == 0) {
          success(entity.data);
        } else {
          error(ErrorEntity(code: entity.state, message: entity.msg));
        }
      }
    } on DioError catch (e) {
      error(createErrorEntity(e));
    }
  }

  Future request<T>(String path,
      {Method method = Method.POST,
      dynamic params,
      required Function(T) success,
      required Function(ErrorEntity) error}) async {
    _dio ??= createDio();

    Response response = await _dio!.request(path,
        data: params, options: Options(method: MethodValues[method]));

    try {
      if (response.statusCode == 200) {
        BaseEntity<T> entity = BaseEntity<T>.fromJson(response.data);
        if (entity.state == 0) {
          success(entity.data);
        } else {
          error(ErrorEntity(code: entity.state, message: entity.msg));
        }
      }
    } on DioError catch (e) {
      error(createErrorEntity(e));
    }
  }
}

ErrorEntity createErrorEntity(DioError error) {
  switch (error.type) {
    case DioErrorType.cancel:
      {
        return ErrorEntity(code: -1, message: "请求取消");
      }
    case DioErrorType.connectTimeout:
      {
        return ErrorEntity(code: -1, message: "连接超时");
      }
    case DioErrorType.sendTimeout:
      {
        return ErrorEntity(code: -1, message: "请求超时");
      }
    case DioErrorType.receiveTimeout:
      {
        return ErrorEntity(code: -1, message: "响应超时");
      }
    case DioErrorType.response:
      {
        try {
          int errCode = error.response!.statusCode!;
          switch (errCode) {
            case 400:
              {
                return ErrorEntity(code: errCode, message: "请求语法错误");
              }
            case 403:
              {
                return ErrorEntity(code: errCode, message: "服务器拒绝执行");
              }
            case 404:
              {
                return ErrorEntity(code: errCode, message: "无法连接服务器");
              }
            case 405:
              {
                return ErrorEntity(code: errCode, message: "请求方法被禁止");
              }
            case 500:
              {
                return ErrorEntity(code: errCode, message: "服务器内部错误");
              }
            case 502:
              {
                return ErrorEntity(code: errCode, message: "无效的请求");
              }
            case 503:
              {
                return ErrorEntity(code: errCode, message: "服务器挂了");
              }
            case 505:
              {
                return ErrorEntity(code: errCode, message: "不支持HTTP协议请求");
              }
            default:
              {
                return ErrorEntity(code: errCode, message: "未知错误");
              }
          }
        } on Exception catch (_) {
          return ErrorEntity(code: -1, message: "未知错误");
        }
      }
    default:
      {
        return ErrorEntity(code: -1, message: error.message);
      }
  }
}

enum Method { GET, POST, DELETE, PUT, PATCH, HEAD }

const MethodValues = {
  Method.GET: "get",
  Method.POST: "post",
  Method.DELETE: "delete",
  Method.PUT: "put",
  Method.PATCH: "patch",
  Method.HEAD: "head",
};
